// src/main/java/org/example/backend/service/EvaluationService.java
package org.example.backend.service;

import org.example.backend.dto.EvaluationDto;
import org.example.backend.entity.Evaluation;
import org.example.backend.entity.Internship;
import org.example.backend.exception.BusinessException;
import org.example.backend.exception.ResourceNotFoundException;
import org.example.backend.repository.EvaluationRepository;
import org.example.backend.repository.InternshipRepository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Transactional
public class EvaluationService {

    private final EvaluationRepository evaluationRepository;
    private final InternshipRepository internshipRepository;

    public EvaluationService(EvaluationRepository evaluationRepository,
                           InternshipRepository internshipRepository) {
        this.evaluationRepository = evaluationRepository;
        this.internshipRepository = internshipRepository;
    }

    /**
     * 创建评定记录（教师版）
     */
    public Evaluation createEvaluation(EvaluationDto evaluationDto, Long teacherId) {
        return createEvaluationInternal(evaluationDto, teacherId, 1);
    }

    /**
     * 创建评定记录（企业版）
     */
    public Evaluation createEvaluation(EvaluationDto evaluationDto, Long companyId, Integer evaluatorType) {
        return createEvaluationInternal(evaluationDto, companyId, evaluatorType);
    }

    /**
     * 创建评定记录内部方法
     */
    private Evaluation createEvaluationInternal(EvaluationDto evaluationDto, Long evaluatorId, Integer evaluatorType) {
        // 检查实习是否存在
        Internship internship = internshipRepository.findById(evaluationDto.getInternshipId())
                .orElseThrow(() -> new ResourceNotFoundException("实习信息不存在"));

        // 检查是否已有该评定者的评定记录
        if (evaluationRepository.existsByInternshipIdAndEvaluatorTypeAndEvaluatorId(
                evaluationDto.getInternshipId(), evaluatorType, evaluatorId)) {
            throw new BusinessException("已存在对该实习的评定记录");
        }

        Evaluation evaluation = new Evaluation();
        evaluation.setInternshipId(evaluationDto.getInternshipId());
        evaluation.setEvaluatorType(evaluatorType);
        evaluation.setEvaluatorId(evaluatorId);
        evaluation.setStudentId(evaluationDto.getStudentId());
        evaluation.setScore(evaluationDto.getScore());
        evaluation.setComment(evaluationDto.getComment());
        evaluation.setEvaluatedAt(new Date());

        Evaluation savedEvaluation = evaluationRepository.save(evaluation);

        // 检查是否双方都已完成评定，如果是则自动终止实习
        checkAndTerminateInternship(evaluationDto.getInternshipId());

        return savedEvaluation;
    }

    /**
     * 检查并终止实习
     */
    private void checkAndTerminateInternship(Long internshipId) {
        // 检查是否教师和企业都已完成评定
        boolean teacherEvaluated = evaluationRepository.existsByInternshipIdAndEvaluatorTypeAndEvaluatorId(
                internshipId, 1, internshipRepository.findById(internshipId).get().getTeacherId());
        boolean companyEvaluated = evaluationRepository.existsByInternshipIdAndEvaluatorType(internshipId, 2);

        // 如果实习状态为进行中，且双方都已完成评定，则终止实习
        Internship internship = internshipRepository.findById(internshipId).get();
        if (internship.getStatus() == 1 && teacherEvaluated && companyEvaluated) {
            internship.setStatus(3); // 3表示已终止
            internshipRepository.save(internship);
        }
    }

    /**
     * 获取学生的评定记录
     */
    @Transactional(readOnly = true)
    public Page<Evaluation> getEvaluationsByStudent(Long studentId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "evaluatedAt"));
        return evaluationRepository.findByStudentId(studentId, pageable);
    }

    /**
     * 获取实习的评定记录
     */
    @Transactional(readOnly = true)
    public Page<Evaluation> getEvaluationsByInternship(Long internshipId, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "evaluatedAt"));
        return evaluationRepository.findByInternshipId(internshipId, pageable);
    }

    /**
     * 获取评定者的评定记录
     */
    @Transactional(readOnly = true)
    public Page<Evaluation> getEvaluationsByEvaluator(Long evaluatorId, Integer evaluatorType, int page, int size) {
        Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "evaluatedAt"));
        return evaluationRepository.findByEvaluatorTypeAndEvaluatorId(evaluatorType, evaluatorId, pageable);
    }

    /**
     * 获取实习的所有评定记录
     */
    @Transactional(readOnly = true)
    public List<Evaluation> getEvaluationsByInternship(Long internshipId) {
        return evaluationRepository.findByInternshipId(internshipId);
    }

    /**
     * 检查企业是否已对指定实习进行评定
     */
    @Transactional(readOnly = true)
    public boolean hasEvaluationByCompany(Long internshipId, Long companyId) {
        return evaluationRepository.existsByInternshipIdAndEvaluatorTypeAndEvaluatorId(
                internshipId, 2, companyId);
    }

    /**
     * 更新评定记录
     */
    public Evaluation updateEvaluation(Long evaluationId, EvaluationDto evaluationDto, Long evaluatorId, Integer evaluatorType) {
        Evaluation evaluation = evaluationRepository.findById(evaluationId)
                .orElseThrow(() -> new ResourceNotFoundException("评定记录不存在"));

        // 检查是否是本人评定的记录
        if (!evaluation.getEvaluatorId().equals(evaluatorId) || !evaluation.getEvaluatorType().equals(evaluatorType)) {
            throw new BusinessException("无权限修改该评定记录");
        }

        evaluation.setScore(evaluationDto.getScore());
        evaluation.setComment(evaluationDto.getComment());
        evaluation.setEvaluatedAt(new Date());

        return evaluationRepository.save(evaluation);
    }
}
